package com.qububu.emporium.shoppingCart.control;

import static com.qububu.utils.ParamConverter.assertNotEmpty;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import com.qububu.emporium.shoppingCart.dto.CartSaveGoodsMessageDto;
import com.qububu.emporium.shoppingCart.service.ShoppingCartService;
import com.qububu.systemBase.exceptions.NotFindCartException;
import com.qububu.utils.SystemConstants;

/**
 * @功能：商城购物控制器
 * @详情：主要针对购物车操作
 * @备注 整个流程需要过滤,没有登录则提示
 * */
@Controller
@RequestMapping("/cart")
public class ShoppingCartControl {

	/**
	 *  购物车设计: sessionId-{
	 *  	SystemConstants.CART_TOTAL_PRICE_KEY: 商品总价(Double)
	 *  	SystemConstants.CART_GOODSNUM_KEY: 商品数量(Integer)
	 *  	SystemConstants.CART_GOODS_LIST: 商品列表(Map<String, CartSaveGoodsMessageDto>)
	 *  }
	 **/
	@Resource
	private ShoppingCartService shoppingCartService;
	
	/**
	 * @author ZCW
	 * @throws NotFindCartException
	 * @功能 添加商品进入购物车
	 * @备注 整个流程需要同步操作,避免并发时出错
	 * */
	@SuppressWarnings("unchecked")
	@RequestMapping("/add")
	@ResponseBody
	public Map<String, Object> addGoodsToCart(HttpServletRequest request) throws NotFindCartException {
		
		// sync可以考虑使用Spring的aop
		synchronized (request) {
			// 获取header中的信息
			HttpSession session = request.getSession();
			String goodsId = assertNotEmpty(request.getParameter("gd")); // gd代表商品id
			String cartId = session.getId();
			Map<String, Object> cartMap = null;
			Map<String, CartSaveGoodsMessageDto> goodsMap = null;
			if (session.getAttribute(cartId) == null) {
				cartMap = new HashMap<String, Object>();
				goodsMap = new HashMap<String, CartSaveGoodsMessageDto>();
				cartMap.put(SystemConstants.CART_TOTAL_PRICE_KEY, new Double(0));
				cartMap.put(SystemConstants.CART_GOODSNUM_KEY, new Integer(0));
				cartMap.put(SystemConstants.CART_GOODS_MAP, goodsMap);
				session.setAttribute(cartId, cartMap);
//				setCartIdentification(request);
			} else {
				cartMap = (Map<String, Object>) session.getAttribute(cartId);
				goodsMap = (Map<String, CartSaveGoodsMessageDto>) cartMap.get(SystemConstants.CART_GOODS_MAP);
			}
			CartSaveGoodsMessageDto cartSaveGoodsMessage = shoppingCartService.getCartSaveGoodsMessageByGoodsId(goodsId);
			goodsMap.put(goodsId, cartSaveGoodsMessage);
			double totalPrice = (Double) cartMap.get(SystemConstants.CART_TOTAL_PRICE_KEY) + Double.parseDouble(cartSaveGoodsMessage.getGoodsPrice());
			cartMap.put(SystemConstants.CART_TOTAL_PRICE_KEY, totalPrice);
			int goodsNum = (Integer) cartMap.get(SystemConstants.CART_GOODSNUM_KEY) + 1;
			cartMap.put(SystemConstants.CART_GOODSNUM_KEY, goodsNum);

			return getSuccessReturn(totalPrice, goodsNum);
		}
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping("/addGoodsNum")
	@ResponseBody
	public Map<String, Object> addGoodsNum(HttpServletRequest req) throws Exception {

		synchronized (req) {
			Map<String, Object> resultMap = new HashMap<String, Object>();
			String goodsId = assertNotEmpty(req.getParameter("gd"));
			HttpSession session = req.getSession();
			String cartId = session.getId();
			if (session.getAttribute(cartId) == null) {
				// 抛异常
				throw new Exception("购物车中改变商品数量时购物车为初始化, 可能是session过期或者系统攻击");
			}
			Map<String, Object> cartMap = (Map<String, Object>) session.getAttribute(cartId);
			Map<String, CartSaveGoodsMessageDto> goodsMap = (Map<String, CartSaveGoodsMessageDto>) cartMap.get(SystemConstants.CART_GOODS_MAP);
			if (goodsMap.get(goodsId) == null) {
				// 抛异常
				throw new Exception("购物车中改变商品数量时不存在想要修改的商品, 疑是系统攻击");
			}
			CartSaveGoodsMessageDto goods = goodsMap.get(goodsId);
			int goodsQuantity = goods.getGoodsQuantity();
			if (goodsQuantity < 1) {
				resultMap.put("result", SystemConstants.AJAX_FAILED_ALERT);
				throw new Exception("购物车中添加商品数量时商品数量小于1, 疑是系统攻击");
			} else {
				goods.setGoodsQuantity(goodsQuantity + 1);
//				double totalPrice = (Double)session.getAttribute(SystemConstants.CART_TOTAL_PRICE_KEY) + Double.parseDouble(goods.getGoodsPrice());
//				session.setAttribute(SystemConstants.CART_TOTAL_PRICE_KEY, totalPrice);
//				double totalPrice = (Double) cartMap.get(SystemConstants.CART_TOTAL_PRICE_KEY);
//				totalPrice += Double.parseDouble(goods.getGoodsPrice());
//				int goodsNum = (Integer) cartMap.get(SystemConstants.CART_GOODSNUM_KEY);
//				goodsNum += 1;
				double totalPrice = (Double) cartMap.get(SystemConstants.CART_TOTAL_PRICE_KEY) + Double.parseDouble(goods.getGoodsPrice());
				cartMap.put(SystemConstants.CART_TOTAL_PRICE_KEY, totalPrice);
				int goodsNum = (Integer) cartMap.get(SystemConstants.CART_GOODSNUM_KEY) + 1;
				cartMap.put(SystemConstants.CART_GOODSNUM_KEY, goodsNum);
				return getSuccessReturn(totalPrice, goodsNum);
			}
		}
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping("/reduceGoodsNum")
	@ResponseBody
	public Map<String, Object> reduceGoodsNum(HttpServletRequest req) throws Exception {

		synchronized (req) {
			String goodsId = assertNotEmpty(req.getParameter("gd"));
			HttpSession session = req.getSession();
			String cartId = session.getId();
			if (session.getAttribute(cartId) == null) {
				// 抛异常
				throw new Exception("购物车中改变商品数量时购物车为初始化, 可能是session过期或者系统攻击");
			}
			Map<String, Object> cartMap = (Map<String, Object>) session.getAttribute(cartId);
			Map<String, CartSaveGoodsMessageDto> goodsMap = (Map<String, CartSaveGoodsMessageDto>) cartMap.get(SystemConstants.CART_GOODS_MAP);
			if (goodsMap.get(goodsId) == null) {
				// 抛异常
				throw new Exception("购物车中改变商品数量时不存在想要修改的商品, 疑是系统攻击");
			}
			CartSaveGoodsMessageDto goods = goodsMap.get(goodsId);
			int goodsQuantity = goods.getGoodsQuantity();
			if (goodsQuantity < 1){
				Map<String, Object> resultMap = new HashMap<String, Object>();
				resultMap.put("result", SystemConstants.AJAX_FAILED_ALERT);
				throw new Exception("购物车中减少商品数量时商品数量小于1, 疑是系统攻击");
			} else {
				goods.setGoodsQuantity(goodsQuantity - 1);
//				double totalPrice = (Double)session.getAttribute(SystemConstants.CART_TOTAL_PRICE_KEY) - Double.parseDouble(goods.getGoodsPrice());
//				session.setAttribute(SystemConstants.CART_TOTAL_PRICE_KEY, totalPrice);
//				double totalPrice = (Double) cartMap.get(SystemConstants.CART_TOTAL_PRICE_KEY);
//				totalPrice -= Double.parseDouble(goods.getGoodsPrice());
//				int goodsNum = (Integer) cartMap.get(SystemConstants.CART_GOODSNUM_KEY);
//				goodsNum -= 1;
				double totalPrice = (Double) cartMap.get(SystemConstants.CART_TOTAL_PRICE_KEY) - Double.parseDouble(goods.getGoodsPrice());
				cartMap.put(SystemConstants.CART_TOTAL_PRICE_KEY, totalPrice);
				int goodsNum = (Integer) cartMap.get(SystemConstants.CART_GOODSNUM_KEY) - 1;
				cartMap.put(SystemConstants.CART_GOODSNUM_KEY, goodsNum);
				
				return getSuccessReturn(totalPrice, goodsNum);
			}
		}
	}
	
	/**
	 * @功能 查询出购物车的数据
	 * */
	@SuppressWarnings("unchecked")
	/*@RequestMapping("/shoppingCartMessage")
	public String searchCartMessage(HttpServletRequest request) {
		
		synchronized (request) {
			HttpSession session = request.getSession();
			Map<String, Object> goodsMap = shoppingCartService.getCartResultMap((Map<String, CartSaveGoodsMessageDto>) session.getAttribute(session.getId()));
			session.setAttribute(SystemConstants.CART_TOTAL_PRICE_KEY, goodsMap.get(SystemConstants.CART_TOTAL_PRICE_KEY));
			request.setAttribute("goodsMessage", goodsMap);
			request.setAttribute("cartBase", session.getAttribute(SystemConstants.CART_IDENTIFICATION_KEY));
			
			return "phoneShowSelectGoods";
		}
	}*/
	@RequestMapping("/shoppingCartMessage")
	@ResponseBody
	public Map<String, Object> searchCartMessage(HttpServletRequest request) {
		
		synchronized (request) {
			HttpSession session = request.getSession();
			Map<String, Object> resultMap = new HashMap<String, Object>();
			Map<String, Object> cartMap = (Map<String, Object>) session.getAttribute(session.getId());
			List<CartSaveGoodsMessageDto> goodsList = shoppingCartService.getCartGoodsList((Map<String, CartSaveGoodsMessageDto>) cartMap.get(SystemConstants.CART_GOODS_MAP));
			resultMap.put("goodsList", goodsList);
			resultMap.put("tp", cartMap.get(SystemConstants.CART_TOTAL_PRICE_KEY));// 商品总价格
//			resultMap.put("tg", cartMap.get(SystemConstants.CART_GOODSNUM_KEY));// 总的商品数量
			resultMap.put("result", SystemConstants.AJAX_SUCCESS);
			return resultMap;
		}
	}
	
	@SuppressWarnings("unchecked")
	@RequestMapping("/remove")
	@ResponseBody
	public Map<String, Object> removeGoodsFromCart(HttpServletRequest request) throws Exception {
		
		synchronized (request) {
			String goodsId = assertNotEmpty(request.getParameter("gd"));// gd表示商品id
			Map<String, Object> resultMap = new HashMap<String, Object>();
			HttpSession session = request.getSession();
			String cartId = session.getId();
			if (session.getAttribute(cartId) == null) {
				resultMap.put("result", SystemConstants.AJAX_FAILED_ALERT); // session过期或者系统攻击
				
				return resultMap;
			} else {
				Map<String, Object> cartMap = (Map<String, Object>) session.getAttribute(cartId);
				Map<String, CartSaveGoodsMessageDto> goodsMap = (Map<String, CartSaveGoodsMessageDto>) cartMap.get(SystemConstants.CART_GOODS_MAP);
//				goodsMap = (Map<String, CartSaveGoodsMessageDto>) session.getAttribute(cartId);
				if (goodsMap.get(goodsId) == null) {
					
					throw new Exception("购物车中移除商品时不存在商品, 疑是系统攻击");
				} else {
					CartSaveGoodsMessageDto goods = goodsMap.get(goodsId);
					goodsMap.remove(goodsId);
//					double totalPrice = (Double) cartMap.get(SystemConstants.CART_TOTAL_PRICE_KEY);
//					totalPrice -= (Double.parseDouble(goods.getGoodsPrice()) * goods.getGoodsQuantity());
//					int goodsNum = (Integer) cartMap.get(SystemConstants.CART_GOODSNUM_KEY);
//					goodsNum -= goods.getGoodsQuantity();
					double totalPrice = (Double) cartMap.get(SystemConstants.CART_TOTAL_PRICE_KEY) - (Double.parseDouble(goods.getGoodsPrice()) * goods.getGoodsQuantity());
					cartMap.put(SystemConstants.CART_TOTAL_PRICE_KEY, totalPrice);
					int goodsNum = (Integer) cartMap.get(SystemConstants.CART_GOODSNUM_KEY) - goods.getGoodsQuantity();
					cartMap.put(SystemConstants.CART_GOODSNUM_KEY, goodsNum);
					
					return getSuccessReturn(totalPrice, goodsNum);
				}
			}
		}
	}
	
	/*@RequestMapping("/remove")
	@ResponseBody
	public Map<String, Object> removeGoodsFromCart(HttpServletRequest request) {
		
		synchronized (request) {
			String goodsId = assertNotEmpty(request.getParameter("gd"));// gd表示商品id
			Map<String, Object> resultMap = new HashMap<String, Object>();
			Map<String, CartSaveGoodsMessageDto> goodsMap = null;
			
			HttpSession session = request.getSession();
			String cartId = session.getId();
			if (session.getAttribute(cartId) == null) {
				resultMap.put("result", SystemConstants.AJAX_FAILED_ALERT); // session过期或者系统攻击
			} else {
				goodsMap = (Map<String, CartSaveGoodsMessageDto>) session.getAttribute(cartId);
				goodsMap.remove(goodsId);
				resultMap.put("result", SystemConstants.AJAX_SUCCESS);
			}
			
			return resultMap;
		}
	}*/

	private Map<String, Object> getSuccessReturn(double totalPrice, int totalGoodsNum) {
		Map<String, Object> successMap = new HashMap<String, Object>();
		successMap.put("tp", totalPrice);// 商品总价格
		successMap.put("tg", totalGoodsNum);// 总的商品数量
		successMap.put("result", SystemConstants.AJAX_SUCCESS);
		
		return successMap;
	}
	
	/**
	 * 修改当前总价和总份数
	 * */
	/*private void changeShoppingCartTotalPriceAndGoodsNum(Map<String, Object> cartMap, double money) {
		
	}*/
	
	/**
	 * @功能 从购物车中删除商品
	 * */
/*	@RequestMapping("/deleteCartAllGoods")
	public Map<String, Object> deleteAllGoodsForCart(HttpServletRequest request) {

		synchronized (request) {
			
			HttpSession session = request.getSession();
			session.removeAttribute(session.getId());
			
			return getSuccessReturn();
		}
		
	}*/
}
